package com.zhongwang.qctApp.view

import android.Manifest
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.os.Parcelable
import android.provider.MediaStore
import android.text.format.DateFormat
import android.view.KeyEvent
import android.view.View
import android.webkit.*
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.zhongwang.qctApp.R
import com.zhongwang.qctApp.utils.SysConfig
import kotlinx.android.synthetic.main.activity_index.*
import java.io.File
import java.util.*
import kotlin.system.exitProcess

class IndexActivity : AppCompatActivity() {
    //自身上下文
    private val indexContent = this
    var requestStatus: String = "SUCCESS"
    //android5版本之前的文件流
    private var mUploadCallbackAboveL: ValueCallback<Array<Uri?>?>? = null

    //android5版本的文件流
    private var mUploadCallbackBelow: ValueCallback<Uri>? = null

    //拍照文件的系统级物理路径
    private var imageUri: Uri? = null

    //获取文件码
    private val REQUEST_CODE = 5378
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_index)
        val permissions = arrayOf(
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.VIBRATE,
            Manifest.permission.INTERNET,
            Manifest.permission.ACCESS_NETWORK_STATE,
            Manifest.permission.ACCESS_WIFI_STATE,
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.WAKE_LOCK,
            Manifest.permission.CAMERA,
            Manifest.permission.RECORD_AUDIO
        )
        var isPass: Boolean = true
        for (per in  permissions){
            var rc = ActivityCompat.checkSelfPermission(this,per)
            if(rc != PackageManager.PERMISSION_GRANTED){
                ActivityCompat.requestPermissions(this,permissions,0)
                isPass = false
            }
        }
        if(isPass){
            // 获取设置接口
            val settings = wv_index.settings
            // 支持JavaScript
            settings.javaScriptEnabled = true
            // 启动缓存
            settings.setAppCacheEnabled(true)
            //设置缓存模式
            settings.cacheMode = WebSettings.LOAD_DEFAULT
            //设置缓存路径
            settings.setAppCachePath(cacheDir.path)
            //设置不支持缩放 android 4 - android 5
            settings.setSupportZoom(false)
            //设置不支持缩放 android 5 - android 6
            settings.builtInZoomControls = false
            //设置不支持缩放 android 7 以上
            settings.displayZoomControls = false
            //块网络影像
            settings.blockNetworkImage = false
            //WebView是否应加载图像资源
            settings.loadsImagesAutomatically = true
            // 更多网络视图设置
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                //开启安全浏览模式
                settings.safeBrowsingEnabled = true
            }
            //是否弃用站点端口
            settings.useWideViewPort = true
            //缩放至屏幕的大小
            settings.loadWithOverviewMode = true
            //支持通过JS打开新窗口
            settings.javaScriptCanOpenWindowsAutomatically = true
            // 弃用浏览器内置数据库作为临时存储令牌使用
            settings.domStorageEnabled = true
            //是否开启多窗口
            settings.setSupportMultipleWindows(false)
            //是否获取位置
            settings.setGeolocationEnabled(true)
            //是否允许访问文件
            settings.allowFileAccess = true
            //webview setting
            /* 如果SDK版本大于19，则激活硬件加速否则激活软件加速（必开，否则页面会卡顿） */
            wv_index.setLayerType(View.LAYER_TYPE_HARDWARE, null)
            // 获取设置接口
            val loadingSettings = wv_loading.settings
            // 支持JavaScript
            loadingSettings.javaScriptEnabled = true
            // 启动换成
            loadingSettings.setAppCacheEnabled(false)
            //设置缓存模式
            loadingSettings.cacheMode = WebSettings.LOAD_NO_CACHE
            //设置缓存路径
            loadingSettings.setAppCachePath(cacheDir.path)
            //不支持缩放
            loadingSettings.setSupportZoom(false)
            //设置不支持缩放
            loadingSettings.builtInZoomControls = false
            //设置不支持缩放
            loadingSettings.displayZoomControls = false
            //块网络影像
            loadingSettings.blockNetworkImage = false
            //WebView是否应加载图像资源
            loadingSettings.loadsImagesAutomatically = true
            // 更多网络视图设置
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                //开启安全浏览模式
                loadingSettings.safeBrowsingEnabled = true
            }
            //是否弃用站点端口
            loadingSettings.useWideViewPort = true
            //缩放至屏幕的大小
            loadingSettings.loadWithOverviewMode = true
            //支持通过JS打开新窗口
            loadingSettings.javaScriptCanOpenWindowsAutomatically = true
            // 弃用浏览器内置数据库作为临时存储令牌使用
            loadingSettings.domStorageEnabled = true
            //是否开启多窗口
            loadingSettings.setSupportMultipleWindows(false)
            //是否获取位置
            loadingSettings.setGeolocationEnabled(true)
            //是否允许访问文件
            loadingSettings.allowFileAccess = true
            wv_loading.setLayerType(View.LAYER_TYPE_HARDWARE, null)
            //针对华为、魅族、小米、OPPO、VIVO、酷派、荣耀、红魔、高端红米手机、努比亚、中兴、真我、三星、LG、海尔、索尼、诺基亚、BQ、朵唯、锤子、天语WebView的0Day漏洞的处理方案，
            //因为这几个厂商修改了WebView源代码，因遵守工信部规则把后台自动手机数据到google的服务代码给删除了，导致了WebView闪退和不自动清除缓存的BUG。所以每次登陆app则自动清除缓存。
            //弊端就是手机不缓存页面，比较浪费流量。
            wv_loading.clearCache(true)
            wv_loading.clearFormData()
            wv_loading.clearHistory()
            wv_index.setLayerType(View.LAYER_TYPE_HARDWARE, null)
            wv_index.clearCache(true)
            wv_index.clearFormData()
            wv_index.clearHistory()
            CookieManager.getInstance().removeAllCookies(null)
            CookieManager.getInstance().flush()
            try {
                val webClient = object : WebViewClient() {
                    /**
                     * 拦截URL请求
                     */
                    override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
                        //url如果包含scan参数值，就是h5和android的协议值，调用本地扫码程序
                        if (url != null && url.contains("/scan/")) {
                            //此请求最有一位字符串 功能对照：1是申请质检，2是质检，3是接收，4是入库质检
                            when (url.substring(url.lastIndex)) {
                                "1" -> {
                                    doScan("applyCheck")
                                }
                                "2" -> {
                                    doScan("check")
                                }
                                "3" -> {
                                    doScan("receive")
                                }
                                "4" -> {
                                    doScan("warehousingCheck")
                                }
                            }
                            return true
                        }
                        else if (url != null) {
                            if(!url.contains("/result")){
                                view?.loadUrl(url)
                            }
                        }
                        return true
                    }

                    /**
                     * 加载页面完毕处理
                     */
                    override fun onPageFinished(view: WebView?, url: String?) {
                        super.onPageFinished(view, url)
                        //显示登陆使用的WebView
                        wv_index.visibility = View.VISIBLE
                        //隐藏加载使用的WebView
                        wv_loading.visibility = View.GONE
                    }

                    /**
                     * 失败处理
                     */
                    override fun onReceivedError(
                        view: WebView?,
                        request: WebResourceRequest?,
                        error: WebResourceError?
                    ) {
                        super.onReceivedError(view, request, error)
                        if (requestStatus == "SUCCESS") {
                            requestStatus = "ERROR"
                        }
                        view?.loadUrl("file:///android_asset/web/index.html")
                    }
                }
                wv_index.webViewClient = webClient
                wv_index.webChromeClient = object : WebChromeClient() {
                    /**
                     * 8(Android 2.2) <= API <= 10(Android 2.3)回调此方法
                     */
                    private fun openFileChooser(uploadMsg: ValueCallback<Uri>) {
                        // (2)该方法回调时说明版本API < 21，此时将结果赋值给 mUploadCallbackBelow，使之 != null
                        mUploadCallbackBelow = uploadMsg
                        takePhoto()
                    }

                    /**
                     * 11(Android 3.0) <= API <= 15(Android 4.0.3)回调此方法
                     */
                    fun openFileChooser(uploadMsg: ValueCallback<Uri>, acceptType: String) {
                        // 这里我们就不区分input的参数了，直接用拍照
                        openFileChooser(uploadMsg)
                    }

                    /**
                     * 16(Android 4.1.2) <= API <= 20(Android 4.4W.2)回调此方法
                     */
                    fun openFileChooser(
                        uploadMsg: ValueCallback<Uri>,
                        acceptType: String,
                        capture: String
                    ) {
                        // 这里我们就不区分input的参数了，直接用拍照
                        openFileChooser(uploadMsg)
                    }

                    /**
                     * API >= 21(Android 5.0.1)回调此方法
                     */
                    override fun onShowFileChooser(
                        webView: WebView?,
                        valueCallback: ValueCallback<Array<Uri?>?>,
                        fileChooserParams: FileChooserParams?
                    ): Boolean {
                        // (1)该方法回调时说明版本API >= 21，此时将结果赋值给 mUploadCallbackAboveL，使之 != null
                        mUploadCallbackAboveL = valueCallback
                        takePhoto()
                        return true
                    }
                }
                wv_index.loadUrl(SysConfig.SYSTEM_NET_URL)
                //加载加载页（加载页必须封装在android程序中，android_asset对应assets文件夹）
                wv_loading.loadUrl("file:///android_asset/web/loading.html")
            } catch (e: Exception) {
                var c = e.message
            }
        }else{
            Toast.makeText(this, "请开启所有要求的权限，否则此app无法使用。", Toast.LENGTH_LONG).show()
        }
    }
    /**
     * 调用相机
     */
    private fun takePhoto() {
        // 指定拍照存储位置的方式调起相机
        val filePath = (Environment.getExternalStorageDirectory().toString() + File.separator
                + Environment.DIRECTORY_PICTURES + File.separator)
        val fileName =
            "IMG_" + DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA))
                .toString() + ".jpg"
        val captureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        imageUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            getImageContentUri(indexContent, File(filePath + fileName))
        } else {
            //7.0之前 直接获取Uri
            Uri.fromFile(File(filePath + fileName))
        }
        captureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)

        // 选择相册
        val Photo = Intent(
            Intent.ACTION_PICK,
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI
        )
        val chooserIntent = Intent.createChooser(Photo, "Image Chooser")
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayOf<Parcelable>(captureIntent))
        startActivityForResult(chooserIntent, REQUEST_CODE)

    }

    /**
     * 回调函数处理
     * @param requestCode 获取码
     * @param resultCode 返回码
     */
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_CODE) {
            // 经过上边(1)、(2)两个赋值操作，此处即可根据其值是否为空来决定采用哪种处理方法
            if (mUploadCallbackBelow != null) {
                chooseBelow(resultCode, data)
            } else if (mUploadCallbackAboveL != null) {
                chooseAbove(resultCode, data)
            } else {
                Toast.makeText(this, "发生错误", Toast.LENGTH_SHORT).show()
            }
        }
    }

    /**
     * Android API < 21(Android 5.0)版本的回调处理
     * @param resultCode 选取文件或拍照的返回码
     * @param data 选取文件或拍照的返回结果
     */
    private fun chooseBelow(resultCode: Int, data: Intent?) {
        if (RESULT_OK == resultCode) {
            updatePhotos()
            if (data != null) {
                // 这里是针对文件路径处理
                val uri = data.data
                if (uri != null) {
                    mUploadCallbackBelow!!.onReceiveValue(uri)
                } else {
                    mUploadCallbackBelow!!.onReceiveValue(null)
                }
            } else {
                // 以指定图像存储路径的方式调起相机，成功后返回data为空
                mUploadCallbackBelow!!.onReceiveValue(imageUri)
            }
        } else {
            mUploadCallbackBelow!!.onReceiveValue(null)
        }
        mUploadCallbackBelow = null
    }

    /**
     * Android API >= 21(Android 5.0) 版本的回调处理
     * @param resultCode 选取文件或拍照的返回码
     * @param data 选取文件或拍照的返回结果
     */
    private fun chooseAbove(resultCode: Int, data: Intent?) {
        if (RESULT_OK == resultCode) {
            updatePhotos()
            if (data != null) {
                // 这里是针对从文件中选图片的处理
                val results: Array<Uri?>
                val uriData = data.data
                if (uriData != null) {
                    results = arrayOf(uriData)
                    mUploadCallbackAboveL!!.onReceiveValue(results)
                } else {
                    mUploadCallbackAboveL!!.onReceiveValue(null)
                }
            } else {
                if (imageUri != null && imageUri!!.path != null) {
                    mUploadCallbackAboveL!!.onReceiveValue(arrayOf(imageUri))
                }
            }
        } else {
            mUploadCallbackAboveL!!.onReceiveValue(null)
        }
        mUploadCallbackAboveL = null
    }

    /**
     * Search the picture of the physical address at the beginning of file with
     * the system level database to obtain the mapping address (content address),
     * and make the URI object with false identity by shelling camouflage and data
     * conversion. At this time, the URI object shell is the photo album connection,
     * and the internal binary file data is the file data of the physical address,
     * and then use the camouflage identity, Obtain the trust of anti transparent
     * transmission function of Android 7 and above systems in a deceptive way,
     * and transfer the pictures to third-party apps. This technical strategy comes
     * from meta (Facebook).
     * Name:Martin Zarate Rafael
     * Country:Peru
     * Job:Senior Software Engineer
     * 将file开头的物理地址的图片，利用系统级数据库进行搜索获取映射地址（content地址），
     * 使用加壳伪装和数据转换的方式做出假的身份的Uri对象，此时Uri对象壳是相册连接，
     * 内部二进制文件数据是物理地址的文件数据，然后使用伪装身份，以欺骗的方式获取Android7
     * 及以上版本系统防止透传功能的信任，将图片传递给第三方app。此技术策略来源于meta(facebook)。
     * 姓名:马丁·萨拉特·拉斐尔
     * 职位:高级软件工程师
     * 国家：秘鲁
     * 关键技术（加壳透传技术）
     * 使用者经验：此技术可能会造成冗余数据，降低客户的手机性能。
     * （注：注释不要删除和修改，内容用来谷歌搜索，用来解决大坑使用）
     */
    private fun getImageContentUri(context: Context, imageFile: File): Uri? {
        val filePath = imageFile.absolutePath
        val cursor: Cursor? = context.contentResolver.query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, arrayOf(
                MediaStore.Images.Media._ID
            ), MediaStore.Images.Media.DATA + "=? ", arrayOf(filePath), null
        )
        var uri: Uri? = null
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                val intVal: Int = cursor.getColumnIndex(MediaStore.MediaColumns._ID)
                val id: Int = cursor.getInt(intVal)
                val baseUri = Uri.parse("content://media/external/images/media")
                uri = Uri.withAppendedPath(baseUri, "" + id)
            }
            cursor.close()
        }
        if (uri == null) {
            val values = ContentValues()
            values.put(MediaStore.Images.Media.DATA, filePath)
            uri = context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
        }
        return uri
    }

    /***
     * 更新相册
     */
    private fun updatePhotos() {
        // 该广播即使多发（即选取照片成功时也发送）也没有关系，只是唤醒系统刷新媒体文件
        val intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
        intent.data = imageUri
        sendBroadcast(intent)
    }
    // 退出时间
    private var currentBackPressedTime: Long = 0

    // 退出间隔
    private val BACK_PRESSED_INTERVAL: Int = 2000
    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (event != null) {
            if (keyCode == KeyEvent.KEYCODE_BACK && event.repeatCount == 0) {
                closeApp()
                return true
            }
        }
        return super.onKeyDown(keyCode, event)
    }

    //关闭或返回上一页
    private fun closeApp() {
        if (System.currentTimeMillis() - currentBackPressedTime > BACK_PRESSED_INTERVAL) {
            currentBackPressedTime = System.currentTimeMillis()
            wv_index.goBack()
        } else {
            finish()
            exitProcess(0)
        }
    }

    /**
     * 扫码方法
     * 组成 "2021K013|GSJ01-06-2|13092|1" 生产令|图号|部分ID|1(生产转序)或2（转给转序）或3（工艺返修票）或4（重新下料工艺卡）
     */
    private fun doScan(purpose: String) {
        val scanIntent = Intent(this, ScanActivity::class.java)
        scanIntent.putExtra("purpose", purpose)
        startActivity(scanIntent)
    }
}